//
//  memory_pool.cpp
//  JanMalloc
//
//  Created by janhit on 2022/4/16.
//

#include "MemoryPool.hpp"
#include "ThreadAllocator.hpp"
#include "MemItem.hpp"


namespace MMFAlloc{


MemoryPool::MemoryPool()
:
mIsExit(false)
{
    //创建清理线程
    mCleaner = new std::thread([this](){
        while(!mIsExit)
        {
            std::this_thread::sleep_for(std::chrono::seconds(5));
            mLock.Lock();
            for (auto& v:mThdAllocator)
                v.second->Sharink();
            mLock.Unlock();
        }
    });
}


MemoryPool::~MemoryPool()
{
    mIsExit = true;
    mCleaner->join();
    
    for (auto& v: mThdAllocator)
        delete v.second;

}


void* MemoryPool::Alloc(u32 size)
{
    ThreadAllocator* allocator = nullptr;
    static std::thread::id thdId = std::this_thread::get_id();
    mLock.Lock();
    auto iter = mThdAllocator.find(thdId);
    if (iter == mThdAllocator.end())
    {
        allocator = new ThreadAllocator(thdId);
        mThdAllocator.insert({thdId, allocator});
    }
    else
        allocator = iter->second;
    
    mLock.Unlock();
    
    return allocator->Alloc(size);
}


void MemoryPool::Free(void* addr)
{
    MemoryItem* mi = (MemoryItem*)addr - 1;
    
    mLock.Lock();
    auto iter = mThdAllocator.find(mi->ThreadId());
    mLock.Unlock();
    
    if (iter != mThdAllocator.end())
    {
        iter->second->Free(addr);
    }
}


}
